#ifndef LORA_COM_H
#define LORA_COM_H

#include <Arduino.h>
#include <SPI.h>
#include <LoRa.h>

// 定义LoRa通信参数
#define LORA_FREQ 433E6      // 433MHz频段
#define LORA_SPREADING_FACTOR 7
#define LORA_SIGNAL_BANDWIDTH 125E3
#define LORA_CODING_RATE 5
#define LORA_PREAMBLE_LENGTH 8
#define LORA_SYNC_WORD 0x12   // 自定义同步字
#define LORA_POWER 17         // 发射功率，单位dBm

// 消息类型定义
enum MessageType {
  SENSOR_DATA = 1,
  COMMAND = 2,
  ACKNOWLEDGE = 3,
  STATUS = 4
};

// 基本消息结构
typedef struct {
  uint8_t messageType;
  uint8_t senderId;
  uint8_t recipientId;
  uint8_t payloadLength;
} MessageHeader;

class LoRaCom {
private:
  uint8_t ssPin;
  uint8_t rstPin;
  uint8_t dio0Pin;
  uint8_t deviceId;
  
public:
  LoRaCom(uint8_t ss, uint8_t rst, uint8_t dio0, uint8_t id) {
    ssPin = ss;
    rstPin = rst;
    dio0Pin = dio0;
    deviceId = id;
  }
  
  bool begin() {
    // 设置LoRa模块引脚
    LoRa.setPins(ssPin, rstPin, dio0Pin);
    
    // 初始化LoRa模块
    if (!LoRa.begin(LORA_FREQ)) {
      return false;
    }
    
    // 配置LoRa参数
    LoRa.setSpreadingFactor(LORA_SPREADING_FACTOR);
    LoRa.setSignalBandwidth(LORA_SIGNAL_BANDWIDTH);
    LoRa.setCodingRate4(LORA_CODING_RATE);
    LoRa.setPreambleLength(LORA_PREAMBLE_LENGTH);
    LoRa.setSyncWord(LORA_SYNC_WORD);
    LoRa.setTxPower(LORA_POWER);
    
    // 启用CRC校验
    LoRa.enableCrc();
    
    return true;
  }
  
  // 发送消息
  int sendMessage(uint8_t recipientId, uint8_t messageType, uint8_t* payload, uint8_t payloadLength) {
    if (payloadLength > 255 - sizeof(MessageHeader)) {
      return -1; // 负载过大
    }
    
    // 创建消息
    uint8_t message[255];
    MessageHeader* header = (MessageHeader*)message;
    
    // 填充消息头
    header->messageType = messageType;
    header->senderId = deviceId;
    header->recipientId = recipientId;
    header->payloadLength = payloadLength;
    
    // 复制负载数据
    if (payloadLength > 0) {
      memcpy(message + sizeof(MessageHeader), payload, payloadLength);
    }
    
    // 发送消息
    LoRa.beginPacket();
    LoRa.write(message, sizeof(MessageHeader) + payloadLength);
    int result = LoRa.endPacket();
    
    return result;
  }
  
  // 接收消息
  int receiveMessage(uint8_t* buffer, uint8_t bufferSize, uint8_t& senderId, uint8_t& messageType) {
    int packetSize = LoRa.parsePacket();
    if (packetSize == 0) {
      return 0; // 没有接收到数据包
    }
    
    // 检查缓冲区大小是否足够
    if (packetSize > bufferSize + sizeof(MessageHeader)) {
      return -1; // 缓冲区太小
    }
    
    // 读取消息头
    MessageHeader header;
    LoRa.readBytes((uint8_t*)&header, sizeof(MessageHeader));
    
    // 检查是否是发给本设备的消息
    if (header.recipientId != deviceId && header.recipientId != 0xFF) {
      // 不是发给本设备的消息，跳过
      while (LoRa.available()) {
        LoRa.read();
      }
      return 0;
    }
    
    // 保存发送者ID和消息类型
    senderId = header.senderId;
    messageType = header.messageType;
    
    // 读取负载数据
    int payloadRead = 0;
    if (header.payloadLength > 0) {
      payloadRead = LoRa.readBytes(buffer, min(header.payloadLength, bufferSize));
    }
    
    // 跳过剩余字节
    while (LoRa.available()) {
      LoRa.read();
    }
    
    return payloadRead;
  }
  
  // 发送简单文本消息
  int sendText(uint8_t recipientId, const char* text) {
    return sendMessage(recipientId, COMMAND, (uint8_t*)text, strlen(text));
  }
  
  // 发送确认消息
  int sendAck(uint8_t recipientId, uint8_t originalMessageType, uint8_t status) {
    uint8_t payload = status;
    return sendMessage(recipientId, ACKNOWLEDGE, &payload, 1);
  }
  
  // 设置频道（改变频率）
  void setChannel(float frequency) {
    LoRa.begin(frequency);
  }
  
  // 获取最后一次RSSI值
  int getRSSI() {
    return LoRa.packetRssi();
  }
  
  // 获取SNR值
  float getSNR() {
    return LoRa.packetSnr();
  }
};

#endif